﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Moon.Sql
{
    public interface IRepository<TEntity, TKey> : IDisposable where TEntity : class
    {
        IInsertable<TEntity> GetInsertable(TEntity entity);
        IInsertable<TEntity> GetInsertable(List<TEntity> list);
        IInsertable<TEntity> GetInsertable(TEntity entity, string tableName);
        IInsertable<TEntity> GetInsertable(List<TEntity> list, string tableName);

        IUpdateable<TEntity> GetUpdateable(TEntity entity);
        IDeleteable<TEntity> GetDeleteable();
        IDeleteable<TEntity> GetDeleteable(params TKey[] pks);

        IQueryable<TEntity> GetQueryable();

        int Insert(TEntity entity);
        int Insert(List<TEntity> list);
        long InsertGetIdentity(TEntity entity);
        int Insert(TEntity entity, string tableName);
        int Insert(List<TEntity> list, string tableName);
        long InsertGetIdentity(TEntity entity, string tableName);
        int BulkInsert(List<TEntity> list);
        int BulkInsert(List<TEntity> list, string tableName);

        int Delete(TEntity entity);
        int Delete(Expression<Func<TEntity, bool>> where);
        int Delete(params TKey[] pks);
        int DeleteById(TKey id);

        //int Update(TEntity entity);
        int Update(TEntity entity, Expression<Func<TEntity, bool>> where);
        int Update(TEntity entity,
            Expression<Func<TEntity, object>> columns,
            Expression<Func<TEntity, bool>> where,
            Expression<Func<TEntity, object>> ignoreColumns = null);

        List<TEntity> GetList();
        List<TEntity> GetList(Expression<Func<TEntity, bool>> where);
        List<TEntity> GetList(string tableName);
        List<TEntity> GetList(Expression<Func<TEntity, bool>> where, string tableName);
        QueryPageResult<TEntity> GetPageList(Expression<Func<TEntity, bool>> where, int offset, int limit);
        QueryPageResult<TEntity> GetPageList(Expression<Func<TEntity, bool>> where, int offset, int limit, Expression<Func<TEntity, object>> orderField, OrderBy orderBy = Moon.Sql.OrderBy.Asc);
        TEntity GetById(TKey id);
        TEntity GetById(TKey id, string tableName);
        TEntity FirstOrDefault(Expression<Func<TEntity, bool>> where);
        TEntity FirstOrDefault(Expression<Func<TEntity, bool>> where, string tableName);
        #region async
        Task<int> InsertAsync(TEntity entity);
        Task<int> InsertAsync(List<TEntity> list);
        Task<long> InsertGetIdentityAsync(TEntity entity);

        Task<int> DeleteAsync(TEntity entity);
        Task<int> DeleteAsync(Expression<Func<TEntity, bool>> where);
        Task<int> DeleteAsync(params TKey[] pks);

        Task<int> UpdateAsync(TEntity entity, Expression<Func<TEntity, bool>> where);
        Task<int> UpdateAsync(TEntity entity,
            Expression<Func<TEntity, object>> columns,
            Expression<Func<TEntity, bool>> where,
            Expression<Func<TEntity, object>> ignoreColumns = null);

        Task<List<TEntity>> GetListAsync();
        Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> where);
        Task<QueryPageResult<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> where, int offset, int limit);
        Task<QueryPageResult<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> where, int offset, int limit, Expression<Func<TEntity, object>> orderField, OrderBy orderBy = Moon.Sql.OrderBy.Asc);
        Task<int> DeleteByIdAsync(TKey id);
        Task<TEntity> GetByIdAsync(TKey id);
        Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> where);
        #endregion async
    }
}
